package symbal;

import symbal.constsymbal.ConstSymbal;

import java.util.ArrayList;

public class SymbalTable extends SymbalNode {
    private SymbalTable father;
    private ArrayList<SymbalNode> symbals;
    private int index;

    public SymbalTable() {
        this.father = null;
        this.symbals = new ArrayList<>();
        this.index = 0;
    }

    public SymbalTable(SymbalTable father) {
        this.father = father;
        this.symbals = new ArrayList<>();
        this.index = father.getLength();
        father.addSymbal(this);
    }

    public int getLength() {
        return symbals.size();
    }

    public void addSymbal(SymbalNode node) {
        this.symbals.add(node);
    }

    public boolean checkSymbals(String name) {
        return checkSymbals(getLength(), name);
    }

    public boolean checkSymbals(int index, String name) {
        for (int i = 0; i < index; i++) {
            SymbalNode node = symbals.get(i);
            if (node instanceof Symbal) {
                if (((Symbal) node).getName().equals(name)) {
                    return true;
                }
            }
        }
        if (this.father != null) {
            return father.checkSymbals(this.index, name);
        } else {
            return false;
        }
    }

    public boolean checkDupSymbal(String name) {
        for (SymbalNode node: symbals) {
            if (node instanceof Symbal) {
                if (((Symbal) node).getName().equals(name)) {
                    return true;
                }
            }
        }
        return false;
    }

    public Symbal findSymbal(String name) {
        return findSymbal(getLength(), name);
    }

    public ConstSymbal findConst(String name) {
        return findConst(getLength(), name);
    }

    public Symbal findSymbal(int index, String name) {
        for (int i = 0; i < index; i++) {
            SymbalNode node = symbals.get(i);
            if (node instanceof Symbal) {
                if (((Symbal) node).getName().equals(name)) {
                    return (Symbal) node;
                }
            }
        }
        if (this.father != null) {
            return father.findSymbal(this.index, name);
        } else {
            return null;
        }
    }

    public ConstSymbal findConst(int index, String name) {
        for (int i = 0; i < index; i++) {
            SymbalNode node = symbals.get(i);
            if (node instanceof ConstSymbal) {
                if (((ConstSymbal) node).getName().equals(name)) {
                    return (ConstSymbal) node;
                }
            }
        }
        if (this.father != null) {
            return father.findConst(this.index, name);
        } else {
            return null;
        }
    }

    public SymbalTable getFather() {
        return this.father;
    }

    public void clear() {
        this.symbals.clear();
        this.father = null;
        this.index = 0;
    }

    @Override
    public String toString() {
        return "SymbalTable{" +
                "symbals=" + symbals +
                ", index=" + index +
                '}';
    }
}
